module Q.IR.Core where

import Q.IR.Common

--------------------------------------------------------------------------------
-- Core AST

data Expr
  = EInt Int
  | ERef Id Path
  | ECons Expr Expr
  | EOp2 Op2 Expr Expr

data Cont
  = Return
  | Label Id

data Prog
  = PJump Cont Expr
  | PDefn [(Id, LabelDef)] Prog
  | PCases Expr [(Int, Prog)]

data LabelDef = LabelDef
  { lArg  :: Id
  , lArgL :: Layout
  , lBody :: Prog }

--------------------------------------------------------------------------------
-- Operators

data Op2 = Op2Add | Op2Sub | Op2Mul | Op2Div | Op2Mod | Op2Eq | Op2LT
  deriving (Eq, Ord)

cmpOutputBit :: (a -> a -> Bool) -> (a -> a -> Int)
cmpOutputBit cmp x y = if x `cmp` y then 1 else 0

applyOp2 :: Op2 -> Int -> Int -> Int
applyOp2 Op2Add = (+)
applyOp2 Op2Sub = (-)
applyOp2 Op2Mul = (*)
applyOp2 Op2Div = div
applyOp2 Op2Mod = mod
applyOp2 Op2Eq  = cmpOutputBit (==)
applyOp2 Op2LT  = cmpOutputBit (<)
